using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using ExtendedMvc.Elements;

namespace ExtendedMvc {
	public static class FormInputExtensions {

		public static Hidden Hidden<T>(this ModelViewForm<T> form, string memberName, object value = null) where T : class {
			if (value == null) return new Hidden(memberName, form.Helper.ViewContext.ViewData.Eval(memberName));
			else return new Hidden(memberName, value);
		}

		public static Hidden Hidden<T>(this ModelViewForm<T> form, Expression<Func<T, object>> expression) where T : class {
			return new Hidden(expression.GetNameFor(), expression.GetValueFrom(form.Helper.ViewDataContainer.Model));
		}

		public static Label<T> LabelFor<T>(this ModelViewForm<T> form, string memberName, string targetId = null, string id = null) where T : class {
			return new Label<T>(form.Helper, memberName, targetId, id);
		}

		public static Label<T> LabelFor<T>(this ModelViewForm<T> form, Expression<Func<T, object>> expression, string targetId = null, string id = null) where T : class {
			return new Label<T>(form.Helper, expression.GetNameFor(), targetId, id);
		}

		public static DisplayText<T> DisplayText<T>(this ModelViewForm<T> form, string memberName, string value = null, string id = null) where T : class {
			if (value == null) return new DisplayText<T>(form.Helper, memberName, form.Helper.ViewContext.ViewData.Eval(memberName));
			return new DisplayText<T>(form.Helper, memberName, value, id);
		}

		public static DisplayText<T> DisplayText<T>(this ModelViewForm<T> form, Expression<Func<T, object>> expression, string id = null) where T : class {
			return new DisplayText<T>(form.Helper, expression.GetNameFor(), expression.GetValueFrom(form.Helper.ViewDataContainer.Model));
		}

		public static TextBox<T> TextBox<T>(this ModelViewForm<T> form, string memberName, string value = null, string id = null) where T : class {
			if (value == null) return new TextBox<T>(form.Helper, memberName, form.Helper.ViewContext.ViewData.Eval(memberName));
			return new TextBox<T>(form.Helper, memberName, value, id);
		}

		public static TextBox<T> TextBox<T>(this ModelViewForm<T> form, Expression<Func<T, object>> expression, string id = null) where T : class {
			return new TextBox<T>(form.Helper, expression.GetNameFor(), expression.GetValueFrom(form.Helper.ViewDataContainer.Model), id);
		}

		public static Password<T> Password<T>(this ModelViewForm<T> form, string memberName, string value = null, string id = null) where T : class {
			if (value == null) return new Password<T>(form.Helper, memberName, id);
			return new Password<T>(form.Helper, memberName, value);
		}

		public static Password<T> Password<T>(this ModelViewForm<T> form, Expression<Func<T, object>> expression, string id = null) where T : class {
			return new Password<T>(form.Helper, expression.GetNameFor(), id);
		}

		public static CheckBox<T> SingleCheckBox<T>(this ModelViewForm<T> form, string memberName, bool? isChecked = null, string id = null) where T : class {
			var checkIt = isChecked ?? form.Helper.ViewContext.ViewData.Eval(memberName) != null && (form.Helper.ViewContext.ViewData.Eval(memberName) as bool?) != null && (form.Helper.ViewContext.ViewData.Eval(memberName) as bool?) != false;
			return new CheckBox<T>(form.Helper, memberName, form.Helper.ViewContext.ViewData.Eval(memberName), checkIt, id);
		}

		public static CheckBox<T> SingleCheckBox<T>(this ModelViewForm<T> form, Expression<Func<T, bool?>> expression, string id = null) where T : class {
			return new CheckBox<T>(form.Helper, expression.GetNameFor(), expression.GetValueFrom(form.Helper.ViewDataContainer.Model), expression.GetValueFrom(form.Helper.ViewDataContainer.Model).Value, id);
		}

		public static TextArea<T> TextArea<T>(this ModelViewForm<T> form, string memberName, string text = null, string id = null) where T : class {
			if (text == null) return new TextArea<T>(form.Helper, memberName, (form.Helper.ViewContext.ViewData.Eval(memberName) as string), id);
			return new TextArea<T>(form.Helper, memberName, text, id);
		}

		public static TextArea<T> TextArea<T>(this ModelViewForm<T> form, string memberName, IEnumerable<string> lines, string id = null) where T : class {
			return new TextArea<T>(form.Helper, memberName, lines, id);
		}

		public static TextArea<T> TextArea<T>(this ModelViewForm<T> form, Expression<Func<T, string>> expression, string id = null) where T : class {
			return new TextArea<T>(form.Helper, expression.GetNameFor(), expression.GetValueFrom(form.Helper.ViewDataContainer.Model), id);
		}

		public static TextArea<T> TextArea<T>(this ModelViewForm<T> form, Expression<Func<T, IEnumerable<string>>> expression, string id = null) where T : class {
			return new TextArea<T>(form.Helper, expression.GetNameFor(), expression.GetValueFrom(form.Helper.ViewDataContainer.Model), id);
		}

		public static File<T> File<T>(this ModelViewForm<T> form, string memberName, string value = null, string id = null) where T : class {
			if (value == null) return new File<T>(form.Helper, memberName, form.Helper.ViewContext.ViewData.Eval(memberName));
			return new File<T>(form.Helper, memberName, value, id);
		}

		public static File<T> File<T>(this ModelViewForm<T> form, Expression<Func<T, object>> expression, string id = null) where T : class {
			return new File<T>(form.Helper, expression.GetNameFor(), expression.GetValueFrom(form.Helper.ViewDataContainer.Model), id);
		}
	}
}
